<?php
namespace Plu\Library\Services\Tga\Baoming;

use Plu\Library\Services\ServiceBase,
    Plu\Library\Models\Tga\Baoming\Applicants as ApplicantsModel;

/**
 * @usage 
 * $service = new BaomingService($appkey, $uid)
 * $service->validate()
 * $service->register()
 *
 * $service->hasRegistered()
 *
 */
class BaomingService extends ServiceBase {
    //错误代码
    const SUCCESS            = 0;//成功 标识符0
    const ERROR_SIGNED       = -2;//已经报名过
    const ERROR_EMPTY        = -3;//必填项没填
    const ERROR_FORMAT       = -4;//格式错误
    const ERROR_APPKEY       = -5;//appkey错误
    const ERROR_DATA_START   = -6;//比赛未开始
    const ERROR_DATA_END     = -7;//比赛已结束
    const ERROR_APP_UNABLE   = -8;//活动未启用
    const ERROR_HASH_UNMATCH = -9;//传过来的hash 不匹配
    const ERROR_VALIDATION   = -10;//校验失败
    const ERROR_REPEATE   = -12;//已经存在

    protected $_uid;

    protected $_appkey    = null;

    protected $_verified  = false;//验证通过

    protected $_errorInfo = [];

    protected $_passInfo  = [];//验证的通过后的数据

    protected $_postInfo  = [];//把post数据，数据不通过，返回给他编辑用

    protected $_formInfo  = null;

    protected $_appInfo   = null;

    //要检查的类型
    public static $checkTypes = array(
        'default'   => '默认',
        'name'      => '名字', //汉字
        'email'     => '邮箱',
        'qq'        => 'QQ',
        'idcard'    => '身份证',
        'telephone' => '手机号码',
        'string'    => '字符串',
        'int'       => '数字'
    );

    public function __construct($appkey, $uid) {
        $this->_appkey = $appkey;
        $this->_uid    = $uid;

        $this->_redis = new RedisService();
        
        $form = $this->_redis->getFormInfo($appkey);

        if ($form && is_array($form)) {
            $this->_formInfo = $form;
            $this->_appInfo = $this->_redis->getAppInfo($form['appid']);
        }

        $this->now = time();
    }

    //获取表单信息
    public function getFormInfo() {
        return $this->_formInfo;
    }

    //获取活动信息
    public function getAppInfo() {
        return $this->_appInfo;
    }

    /**
     *  报名注册
     *
     *  1. check
     *  2. insert
     */
    public function register(){
        if (!$this->_verified) {
            $this->setErrorMessage(self::ERROR_VALIDATION, 'validation', "校验数据不成功");
            return false;
        }

        $isSuccess = ApplicantsModel::insert($this->_appkey, $this->_uid, $this->now, json_encode($this->_passInfo));

        if ($isSuccess) {
            $this->_redis->set($this->_appkey, $this->_uid, json_encode($this->_passInfo));

            return true;
        }
        return false;
    }
    
    /**
     *  判断是否已经报名
     *  从redis中取
     *  @return bool
     */
    public function hasRegistered(){
        $r = $this->_redis->get($this->_appkey, $this->_uid);

        if (!$r) {
            $info = ApplicantsModel::getItemByUid($appkey, $uid);
            if (!empty($info)) {
                return $info;
            }
            return false;
        }

        return $r;
    }

    /**
     * 校验数据是否合法
     * @param $ignore 不需要uid验证时 $ignore = true
     */
    public function validate($postData, $ignore = false) {
        $app = $this->getAppInfo();

        //比赛未启用
        if ( $app['enable'] != 1 || empty($app) ) {
            $this->setErrorMessage(self::ERROR_APP_UNABLE, 'unable', "不存在该报名活动");
            return false;
        }
        //比赛未开始
        if ( $this->now < $app['starttime']){
            $this->setErrorMessage(self::ERROR_DATA_START, 'starttime', "报名未开始！");
            return false;
        }

        //比赛已经结束
        if( $this->now > $app['endtime']) {
            $this->setErrorMessage(self::ERROR_DATA_END, 'endtime', "报名已结束！");
            return false;
        }

        //判断该用户是否已经报名过了
        if (!$ignore) {
            $hasRegistered = $this->hasRegistered();
            if($hasRegistered){
            $this->setErrorMessage(self::ERROR_SIGNED, 'signed', "您已经报过名了！");
            return false;
            }
        }

     
        $result = $this->_redis->getAll($this->_appkey);
        foreach ($result as $roomid => $value) {
            $value = json_decode($value, true);
            if (isset($value['kplnickname'])) {
                $nicknames[] = $value['kplnickname'];
            } else if (isset($value['telephone'])) {
                $telephones[] = $value['telephone'];
            } else if (isset($value['domain'])) {
                $domains[] = $value['domain'];
            }
        }


        $form = $this->getFormInfo();

        $fields = json_decode($form['fieldlist'], true);
    
        $data = array();

        foreach ($fields as $field) {
            $fieldName = $field['field_name'];


            $item = isset($postData[$fieldName]) ? trim($postData[$fieldName]) : null;

            //必填
            if ($field['isRequired'] == 1) {
                if ((!isset($item)) || $item == '') {
                    $this->setErrorMessage(self::ERROR_EMPTY, $fieldName, $field['name'].'不能为空！');
                    return false;
                }
            }

            //重复
            if ($fieldName == 'telephone') {
                if(in_array($item, $telephones)) {
                    $this->setErrorMessage(self::ERROR_REPEATE, $fieldName, "已经存在!");
                    return false;
                }
            }
            //kplname 重复
            if ($fieldName == 'kplnickname') {
                if(in_array($item, $nicknames)) {
                    $this->setErrorMessage(self::ERROR_REPEATE, $fieldName, "已经存在!");
                    return false;
                }
            }
            //domain 重复
            if ($fieldName == 'domain') {
                if(in_array($item, $domains)) {
                    $this->setErrorMessage(self::ERROR_REPEATE, $fieldName, "已经存在!");
                    return false;
                }
            }


            //微信号检测
            if ($fieldName == 'wechat') {
                $r = preg_match('/^[a-zA-Z]{1}[-_a-zA-Z0-9]{5,19}$/', $item);
                if (!$r){
                    $this->setErrorMessage(self::ERROR_FORMAT, $fieldName, "请填写正确的微信号!");
                    return false;
                }
            }
           

            //类型检查
            if ($field['checktype'] != 'default') {
                $func = $field['checktype'].'Check';
                $r = call_user_func(array(__NAMESPACE__.'\CheckService', $func), $item);
                if (!$r){
                    $this->setErrorMessage(self::ERROR_FORMAT, $fieldName, "请填写正确的{$field['name']}!");
                    return false;
                }
            }

            $data[$field['field_name']] = $item;
        }

        //数据通过
        $this->_passInfo = $data;
        $this->_verified = true;
       return true;
    }

    public function getErrorMessages(){
        return $this->_errorInfo;
    }

    /**
     *  错误设置与获取
     */
    protected function setErrorMessage($errorCode, $field, $errorInfo){
        $this->_errorInfo[] = array(
            'code'      => $errorCode,
            'field'     => $field,
            'errorInfo' => $errorInfo
        );
    }

    /**
     * 获取验证通过的数据
     */
    public function getItems(){
        return $this->_postInfo;
    }


    
}
?>
